/**
 * 材质编辑器
 * 用于编辑3D模型的物理材质属性
 */

import * as THREE from 'three';
import { getMaterialLibraryManager } from './MaterialLibraryManager.js';

export class MaterialEditor {
    constructor() {
        this.modal = null;
        this.currentModel = null;
        this.currentMaterial = null; // 当前选中的材质
        this.currentMaterialSettings = null;
        this.materialLibraryManager = null;
        this.materials = [];
        this.previewScene = null;
        this.previewCamera = null;
        this.previewRenderer = null;
        this.previewMesh = null;
        this.animationId = null;
        
        // 材质预览渲染器
        this.materialPreviews = new Map(); // 存储材质预览渲染器
        
        this.createModal();
        this.createMaterialBrowser();
    }
    
    /**
     * 创建材质编辑器模态窗口
     */
    createModal() {
        this.modal = document.createElement('div');
        this.modal.id = 'material-editor-modal';
        this.modal.className = 'modal';
        this.modal.innerHTML = `
            <div class="modal-content material-editor-content">
                <div class="modal-header">
                    <h2>🎨 材质编辑器</h2>
                    <span id="material-editor-model-name" style="color: rgba(255,255,255,0.5); font-size: 14px; margin-left: 10px;"></span>
                    <button class="modal-close" id="material-editor-close">×</button>
                </div>
                
                <div class="modal-body material-editor-body">
                    <!-- 左上：材质库选择 -->
                    <div class="material-library-selector">
                        <div class="material-selector-header">
                            <h3>材质库</h3>
                            <button class="btn-new-material" id="btn-new-material">+ 新建材质</button>
                        </div>
                        <div class="material-list-container">
                            <div id="material-library-list" class="material-library-list">
                                <!-- 材质列表将在这里渲染 -->
                            </div>
                        </div>
                        <div class="material-actions">
                            <button class="btn-material-action" id="btn-rename-material" disabled>重命名</button>
                            <button class="btn-material-action" id="btn-duplicate-material" disabled>复制</button>
                            <button class="btn-material-action danger" id="btn-delete-material" disabled>删除</button>
                        </div>
                    </div>
                    
                    <!-- 左侧：预览区域 -->
                    <div class="material-preview-container">
                        <div class="preview-label">实时预览</div>
                        <div id="material-preview-canvas" class="material-preview-canvas"></div>
                        <div class="preview-controls">
                            <button class="preview-btn" id="reset-camera-btn" title="重置相机">📷 重置视角</button>
                            <button class="preview-btn" id="reset-material-btn" title="重置材质">🔄 重置材质</button>
                        </div>
                    </div>
                    
                    <!-- 右侧：参数面板 -->
                    <div class="material-params-container">
                        <div class="material-param-section">
                            <h3 class="param-section-title">基础参数</h3>
                            
                            <!-- 基础颜色 -->
                            <div class="param-row">
                                <label class="param-label">基础颜色</label>
                                <div class="param-input-group">
                                    <input type="color" id="mat-color" class="param-color" value="#ffffff">
                                    <input type="text" id="mat-color-hex" class="param-text-short" value="#ffffff" placeholder="#FFFFFF">
                                </div>
                            </div>
                            
                            <!-- 金属度 -->
                            <div class="param-row">
                                <label class="param-label">
                                    金属度
                                    <span class="param-hint">值越大越像金属</span>
                                </label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-metalness" class="param-slider" min="0" max="1" step="0.01" value="0.5">
                                    <input type="number" id="mat-metalness-value" class="param-number" min="0" max="1" step="0.01" value="0.5">
                                </div>
                            </div>
                            
                            <!-- 粗糙度 -->
                            <div class="param-row">
                                <label class="param-label">
                                    粗糙度
                                    <span class="param-hint">值越大表面越粗糙</span>
                                </label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-roughness" class="param-slider" min="0" max="1" step="0.01" value="0.5">
                                    <input type="number" id="mat-roughness-value" class="param-number" min="0" max="1" step="0.01" value="0.5">
                                </div>
                            </div>
                            
                            <!-- 自发光颜色 -->
                            <div class="param-row">
                                <label class="param-label">自发光颜色</label>
                                <div class="param-input-group">
                                    <input type="color" id="mat-emissive" class="param-color" value="#000000">
                                    <input type="text" id="mat-emissive-hex" class="param-text-short" value="#000000" placeholder="#000000">
                                </div>
                            </div>
                            
                            <!-- 自发光强度 -->
                            <div class="param-row">
                                <label class="param-label">
                                    自发光强度
                                    <span class="param-hint">模拟发光效果</span>
                                </label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-emissive-intensity" class="param-slider" min="0" max="2" step="0.1" value="0">
                                    <input type="number" id="mat-emissive-intensity-value" class="param-number" min="0" max="2" step="0.1" value="0">
                                </div>
                            </div>
                        </div>
                        
                        <div class="material-param-section">
                            <h3 class="param-section-title">纹理贴图</h3>
                            
                            <!-- 基础颜色贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    基础颜色贴图
                                    <span class="param-hint">Albedo/Diffuse</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-map" class="param-text" placeholder="贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('map')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('map')" title="清除">×</button>
                                </div>
                            </div>
                            
                            <!-- 法线贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    法线贴图
                                    <span class="param-hint">Normal Map</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-normal-map" class="param-text" placeholder="法线贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('normalMap')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('normalMap')" title="清除">×</button>
                                </div>
                            </div>
                            
                            <!-- 凹凸贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    凹凸贴图
                                    <span class="param-hint">Bump Map</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-bump-map" class="param-text" placeholder="凹凸贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('bumpMap')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('bumpMap')" title="清除">×</button>
                                </div>
                            </div>
                            
                            <!-- 凹凸强度 -->
                            <div class="param-row">
                                <label class="param-label">凹凸强度</label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-bump-scale" class="param-slider" min="0" max="2" step="0.1" value="0">
                                    <input type="number" id="mat-bump-scale-value" class="param-number" min="0" max="2" step="0.1" value="0">
                                </div>
                            </div>
                            
                            <!-- AO贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    AO贴图
                                    <span class="param-hint">Ambient Occlusion</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-ao-map" class="param-text" placeholder="AO贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('aoMap')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('aoMap')" title="清除">×</button>
                                </div>
                            </div>
                            
                            <!-- AO强度 -->
                            <div class="param-row">
                                <label class="param-label">AO强度</label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-ao-intensity" class="param-slider" min="0" max="2" step="0.1" value="1">
                                    <input type="number" id="mat-ao-intensity-value" class="param-number" min="0" max="2" step="0.1" value="1">
                                </div>
                            </div>
                            
                            <!-- 粗糙度贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    粗糙度贴图
                                    <span class="param-hint">Roughness Map</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-roughness-map" class="param-text" placeholder="粗糙度贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('roughnessMap')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('roughnessMap')" title="清除">×</button>
                                </div>
                            </div>
                            
                            <!-- 金属度贴图 -->
                            <div class="param-row">
                                <label class="param-label">
                                    金属度贴图
                                    <span class="param-hint">Metalness Map</span>
                                </label>
                                <div class="param-texture-group">
                                    <input type="text" id="mat-metalness-map" class="param-text" placeholder="金属度贴图路径或URL" readonly>
                                    <button class="param-btn" onclick="selectTextureFile('metalnessMap')">选择文件</button>
                                    <button class="param-btn-clear" onclick="clearTexture('metalnessMap')" title="清除">×</button>
                                </div>
                            </div>
                        </div>
                        
                        <div class="material-param-section">
                            <h3 class="param-section-title">其他设置</h3>
                            
                            <!-- 透明度 -->
                            <div class="param-row">
                                <label class="param-label">透明度</label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-opacity" class="param-slider" min="0" max="1" step="0.01" value="1">
                                    <input type="number" id="mat-opacity-value" class="param-number" min="0" max="1" step="0.01" value="1">
                                </div>
                            </div>
                            
                            <!-- 双面渲染 -->
                            <div class="param-row">
                                <label class="param-label">双面渲染</label>
                                <div class="param-checkbox-group">
                                    <label class="param-checkbox">
                                        <input type="checkbox" id="mat-double-sided">
                                        <span>启用双面渲染</span>
                                    </label>
                                </div>
                            </div>
                        </div>
                        
                        <div class="material-param-section">
                            <h3 class="param-section-title">深度控制（修复重面闪烁）</h3>
                            
                            <!-- 启用多边形偏移 -->
                            <div class="param-row">
                                <label class="param-label">
                                    启用深度偏移
                                    <span class="param-hint">修复Z-Fighting问题</span>
                                </label>
                                <div class="param-checkbox-group">
                                    <label class="param-checkbox">
                                        <input type="checkbox" id="mat-polygon-offset">
                                        <span>启用 PolygonOffset</span>
                                    </label>
                                </div>
                            </div>
                            
                            <!-- 偏移因子 -->
                            <div class="param-row">
                                <label class="param-label">
                                    偏移因子 (Factor)
                                    <span class="param-hint">负值向前，正值向后</span>
                                </label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-polygon-offset-factor" class="param-slider" min="-10" max="10" step="0.1" value="0">
                                    <input type="number" id="mat-polygon-offset-factor-value" class="param-number" min="-10" max="10" step="0.1" value="0">
                                </div>
                            </div>
                            
                            <!-- 偏移单位 -->
                            <div class="param-row">
                                <label class="param-label">
                                    偏移单位 (Units)
                                    <span class="param-hint">固定深度偏移</span>
                                </label>
                                <div class="param-input-group">
                                    <input type="range" id="mat-polygon-offset-units" class="param-slider" min="-10" max="10" step="0.1" value="0">
                                    <input type="number" id="mat-polygon-offset-units-value" class="param-number" min="-10" max="10" step="0.1" value="0">
                                </div>
                            </div>
                            
                            <!-- 深度测试 -->
                            <div class="param-row">
                                <label class="param-label">深度测试</label>
                                <div class="param-checkbox-group">
                                    <label class="param-checkbox">
                                        <input type="checkbox" id="mat-depth-test" checked>
                                        <span>启用深度测试</span>
                                    </label>
                                </div>
                            </div>
                            
                            <!-- 深度写入 -->
                            <div class="param-row">
                                <label class="param-label">深度写入</label>
                                <div class="param-checkbox-group">
                                    <label class="param-checkbox">
                                        <input type="checkbox" id="mat-depth-write" checked>
                                        <span>启用深度写入</span>
                                    </label>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="modal-footer">
                    <button class="modal-btn modal-btn-secondary" id="material-editor-cancel">取消</button>
                    <button class="modal-btn modal-btn-primary" id="material-editor-save">保存材质</button>
                </div>
            </div>
            
            <!-- 隐藏的文件输入 -->
            <input type="file" id="texture-file-input" accept="image/*" style="display:none">
        `;
        
        document.body.appendChild(this.modal);
        
        // 绑定事件
        this.bindEvents();
        
        // 绑定文件选择事件
        this.bindFileInput();
    }
    
    /**
     * 创建材质浏览器窗口
     */
    createMaterialBrowser() {
        const browser = document.createElement('div');
        browser.id = 'material-browser-modal';
        browser.className = 'modal';
        browser.style.display = 'none';
        browser.innerHTML = `
            <div class="modal-content material-browser-content">
                <div class="modal-header">
                    <h2>🎨 材质库</h2>
                    <button class="modal-close" onclick="window.closeMaterialBrowser()">×</button>
                </div>
                
                <div class="modal-body material-browser-body">
                    <!-- 搜索栏 -->
                    <div class="material-browser-search">
                        <input type="text" 
                               id="material-browser-search-input" 
                               class="material-search-field" 
                               placeholder="🔍 搜索材质..."
                               autocomplete="off">
                    </div>
                    
                    <!-- 材质网格 -->
                    <div class="material-browser-grid" id="material-browser-grid">
                        <!-- 材质预览卡片将动态生成 -->
                        <div class="material-grid-loading">加载中...</div>
                    </div>
                </div>
                
                <div class="modal-footer">
                    <button class="modal-btn modal-btn-secondary" onclick="window.closeMaterialBrowser()">取消</button>
                    <button class="modal-btn modal-btn-primary" onclick="window.confirmMaterialSelection()">确定</button>
                </div>
            </div>
        `;
        
        document.body.appendChild(browser);
        this.materialBrowser = browser;
    }
    
    /**
     * 绑定文件输入事件
     */
    bindFileInput() {
        const fileInput = document.getElementById('texture-file-input');
        if (!fileInput) return;
        
        fileInput.onchange = async (e) => {
            const file = e.target.files[0];
            if (!file) return;
            
            const textureType = fileInput.dataset.textureType;
            if (!textureType) return;
            
            // 这里可以上传文件到服务器，然后获取URL
            // 暂时使用本地URL预览（实际项目中需要上传到服务器）
            const localUrl = URL.createObjectURL(file);
            
            const inputMap = {
                'map': 'mat-map',
                'normalMap': 'mat-normal-map',
                'aoMap': 'mat-ao-map',
                'roughnessMap': 'mat-roughness-map',
                'metalnessMap': 'mat-metalness-map'
            };
            
            const inputId = inputMap[textureType];
            if (inputId) {
                const textInput = document.getElementById(inputId);
                if (textInput) {
                    textInput.value = file.name; // 显示文件名
                    textInput.dataset.localUrl = localUrl; // 保存本地URL用于预览
                    
                    // 更新预览
                    this.updatePreview();
                }
            }
            
            // 清空文件输入，允许重复选择同一文件
            fileInput.value = '';
        };
    }
    
    /**
     * 绑定事件监听器
     */
    bindEvents() {
        // 关闭按钮
        document.getElementById('material-editor-close').onclick = () => this.close();
        document.getElementById('material-editor-cancel').onclick = () => this.close();
        
        // 保存按钮
        document.getElementById('material-editor-save').onclick = () => this.save();
        
        // 重置按钮
        document.getElementById('reset-camera-btn').onclick = () => this.resetCamera();
        document.getElementById('reset-material-btn').onclick = () => this.resetMaterial();
        
        // 材质库按钮
        document.getElementById('btn-new-material').onclick = () => this.createNewMaterial();
        document.getElementById('btn-rename-material').onclick = () => this.renameMaterial();
        document.getElementById('btn-duplicate-material').onclick = () => this.duplicateMaterial();
        document.getElementById('btn-delete-material').onclick = () => this.deleteMaterial();
        
        // 参数同步：滑块 <-> 数字输入
        this.bindParamSync('metalness');
        this.bindParamSync('roughness');
        this.bindParamSync('emissive-intensity');
        this.bindParamSync('ao-intensity');
        this.bindParamSync('opacity');
        
        // Bump scale
        if (document.getElementById('mat-bump-scale')) {
            this.bindParamSync('bump-scale');
        }
        
        // 🔧 深度控制参数
        if (document.getElementById('mat-polygon-offset-factor')) {
            this.bindParamSync('polygon-offset-factor');
        }
        if (document.getElementById('mat-polygon-offset-units')) {
            this.bindParamSync('polygon-offset-units');
        }
        
        // 颜色同步：颜色选择器 <-> 十六进制输入
        this.bindColorSync('color');
        this.bindColorSync('emissive');
        
        // 实时预览更新
        this.bindPreviewUpdates();
        
        // 点击模态背景关闭
        this.modal.onclick = (e) => {
            if (e.target === this.modal) {
                this.close();
            }
        };
    }
    
    /**
     * 绑定参数同步（滑块和数字输入框）
     */
    bindParamSync(paramName) {
        const slider = document.getElementById(`mat-${paramName}`);
        const valueInput = document.getElementById(`mat-${paramName}-value`);
        
        if (!slider || !valueInput) return;
        
        slider.oninput = () => {
            valueInput.value = slider.value;
            this.updatePreview();
        };
        
        valueInput.oninput = () => {
            slider.value = valueInput.value;
            this.updatePreview();
        };
    }
    
    /**
     * 绑定颜色同步
     */
    bindColorSync(paramName) {
        const colorPicker = document.getElementById(`mat-${paramName}`);
        const hexInput = document.getElementById(`mat-${paramName}-hex`);
        
        if (!colorPicker || !hexInput) return;
        
        colorPicker.oninput = () => {
            hexInput.value = colorPicker.value;
            this.updatePreview();
        };
        
        hexInput.oninput = () => {
            const value = hexInput.value;
            if (/^#[0-9A-F]{6}$/i.test(value)) {
                colorPicker.value = value;
                this.updatePreview();
            }
        };
    }
    
    /**
     * 绑定所有会影响预览的控件
     */
    bindPreviewUpdates() {
        // 双面渲染
        document.getElementById('mat-double-sided').onchange = () => this.updatePreview();
        
        // 🔧 深度控制复选框
        const polygonOffsetCheckbox = document.getElementById('mat-polygon-offset');
        if (polygonOffsetCheckbox) {
            polygonOffsetCheckbox.onchange = () => this.updatePreview();
        }
        
        const depthTestCheckbox = document.getElementById('mat-depth-test');
        if (depthTestCheckbox) {
            depthTestCheckbox.onchange = () => this.updatePreview();
        }
        
        const depthWriteCheckbox = document.getElementById('mat-depth-write');
        if (depthWriteCheckbox) {
            depthWriteCheckbox.onchange = () => this.updatePreview();
        }
    }
    
    /**
     * 在右侧面板中打开材质编辑器（新模式）
     * @param {Object} modelData - 模型数据
     */
    async openInPanel(modelData) {
        console.warn('⚠️ MaterialEditor.openInPanel() 已弃用，请使用 MaterialEditorPanel');
        
        // 不再覆盖面板内容，避免破坏 MaterialEditorPanel 的搜索功能
        // this.currentModel = modelData;
        // this.materialLibraryManager = getMaterialLibraryManager(modelData.projectId);
        
        // 只切换到材质编辑器 tab
        if (window.rightToolbarManager) {
            window.rightToolbarManager.togglePanel('material-editor');
        }
        
        // ❌ 不再渲染面板内容，避免覆盖 MaterialEditorPanel
        // await this.renderPanelContent(modelData);
    }
    
    /**
     * 渲染面板内容
     * ⚠️ 已弃用：改为使用 MaterialEditorPanel
     */
    async renderPanelContent(modelData) {
        console.warn('⚠️ MaterialEditor.renderPanelContent() 已弃用，不再渲染面板内容');
        return; // 直接返回，不渲染任何内容
        
        // ❌ 以下代码已禁用，避免覆盖 MaterialEditorPanel 的内容
        /*
        const panelBody = document.getElementById('material-editor-body');
        if (!panelBody) {
            console.error('❌ 找不到材质编辑器面板');
            return;
        }
        
        // 更新标题
        const titleEl = document.getElementById('material-editor-title');
        if (titleEl) {
            titleEl.textContent = `材质 - ${modelData.name}`;
        }
        
        // 获取材质类型
        let currentMaterialType = '未知';
        if (modelData.object3D) {
            modelData.object3D.traverse((child) => {
                if (child.isMesh && child.material) {
                    currentMaterialType = child.material.type;
                }
            });
        } else {
            // 从场景中查找节点
            const node = window.sceneTreeManager?.findNodeById?.(window.transformPanel?.currentNode?.id);
            if (node?.object3D) {
                node.object3D.traverse((child) => {
                    if (child.isMesh && child.material) {
                        currentMaterialType = child.material.type;
                    }
                });
            }
        }
        
        // 加载材质设置
        await this.loadMaterialSettings(modelData);
        
        // 渲染紧凑版UI
        panelBody.innerHTML = `
            <div class="material-panel-compact">
                <!-- 材质信息（紧凑） -->
                <div class="material-info-compact">
                    <div class="info-badge">${modelData.name}</div>
                    <div class="info-badge type">${currentMaterialType}</div>
                </div>
                
                <!-- 材质选择器 -->
                <div class="material-selector-compact">
                    <label>当前材质</label>
                    <div class="material-select-wrapper">
                        <input type="text" 
                               id="material-current-name" 
                               class="material-search-input" 
                               placeholder="未选择材质"
                               readonly>
                        <button class="material-browse-btn" id="material-browse-btn" onclick="window.openMaterialBrowser()">
                            📚 浏览材质
                        </button>
                        </div>
                    </div>
                    
                <!-- 材质类型显示 -->
                <div class="material-type-selector">
                    <label>材质类型</label>
                    <div class="material-type-display">
                        Physical (物理材质)
                    </div>
                    <div class="material-type-hint" id="material-type-hint">
                        基于物理的渲染材质，支持金属度、粗糙度、透明度、清漆等高级特性
                        </div>
                    </div>
                    
                <!-- 参数网格布局（动态生成） -->
                <div class="param-grid" id="material-params-container">
                    <!-- 参数将根据材质类型动态生成 -->
                        </div>
                
                <!-- 保存按钮 -->
                <button class="btn-save-compact" onclick="window.materialEditorSave()">💾 保存</button>
                    </div>
        `;
        
        // 固定使用物理材质
        const selectedMaterialType = 'MeshPhysicalMaterial';
        this.updateMaterialTypeHint(selectedMaterialType);
        this.renderParametersByType(selectedMaterialType);
        
        // 加载并绑定材质选择器
        await this.setupMaterialSelector();
        */
    }
    
    /**
     * 更新材质类型提示
     */
    updateMaterialTypeHint(materialType) {
        const hintEl = document.getElementById('material-type-hint');
        if (!hintEl) return;
        
        const hints = {
            'MeshPhysicalMaterial': '🎨 基于物理的渲染材质，支持金属度、粗糙度、透明度、清漆等高级特性'
        };
        
        hintEl.textContent = hints[materialType] || '';
    }
    
    /**
     * 获取材质类型配置
     */
    getMaterialTypeConfig() {
        return {
            'MeshStandardMaterial': {
                params: [
                    { name: 'color', label: '反照率', type: 'color', default: '#ffffff', category: 'Main', hasTexture: 'map' },
                    { name: 'metalness', label: '金属度', type: 'slider', min: 0, max: 1, step: 0.01, default: 0.5, category: 'Main', hasTexture: 'metalnessMap' },
                    { name: 'roughness', label: '粗糙度', type: 'slider', min: 0, max: 1, step: 0.01, default: 0.5, category: 'Main', hasTexture: 'roughnessMap' },
                    { name: 'normalMap', label: '法线贴图', type: 'texture', default: null, category: 'Maps' },
                    { name: 'bumpMap', label: '高度贴图', type: 'texture', default: null, category: 'Maps', hasIntensity: 'bumpScale' },
                    { name: 'aoMap', label: '遮挡贴图', type: 'texture', default: null, category: 'Maps', hasIntensity: 'aoIntensity' },
                    { name: 'emissive', label: '自发光', type: 'color', default: '#000000', category: 'Emission', hasTexture: 'emissiveMap', hasIntensity: 'emissiveIntensity' },
                    { name: 'opacity', label: '不透明度', type: 'slider', min: 0, max: 1, step: 0.01, default: 1.0, category: 'Advanced' }
                ]
            },
            'MeshPhongMaterial': {
                params: [
                    { name: 'color', label: '漫反射', type: 'color', default: '#ffffff', category: 'Main', hasTexture: 'map' },
                    { name: 'specular', label: '高光', type: 'color', default: '#111111', category: 'Main', hasTexture: 'specularMap' },
                    { name: 'shininess', label: '光泽度', type: 'slider', min: 0, max: 100, step: 1, default: 30, category: 'Main' },
                    { name: 'normalMap', label: '法线贴图', type: 'texture', default: null, category: 'Maps' },
                    { name: 'bumpMap', label: '高度贴图', type: 'texture', default: null, category: 'Maps', hasIntensity: 'bumpScale' },
                    { name: 'aoMap', label: '遮挡贴图', type: 'texture', default: null, category: 'Maps' },
                    { name: 'emissive', label: '自发光', type: 'color', default: '#000000', category: 'Emission', hasTexture: 'emissiveMap', hasIntensity: 'emissiveIntensity' },
                    { name: 'opacity', label: '不透明度', type: 'slider', min: 0, max: 1, step: 0.01, default: 1.0, category: 'Advanced' }
                ]
            },
            'MeshLambertMaterial': {
                params: [
                    { name: 'color', label: '漫反射', type: 'color', default: '#ffffff', category: 'Main', hasTexture: 'map' },
                    { name: 'emissive', label: '自发光', type: 'color', default: '#000000', category: 'Emission', hasTexture: 'emissiveMap', hasIntensity: 'emissiveIntensity' },
                    { name: 'aoMap', label: '遮挡贴图', type: 'texture', default: null, category: 'Maps' },
                    { name: 'opacity', label: '不透明度', type: 'slider', min: 0, max: 1, step: 0.01, default: 1.0, category: 'Advanced' }
                ]
            },
            'MeshBasicMaterial': {
                params: [
                    { name: 'color', label: '颜色', type: 'color', default: '#ffffff', category: 'Main', hasTexture: 'map' },
                    { name: 'opacity', label: '不透明度', type: 'slider', min: 0, max: 1, step: 0.01, default: 1.0, category: 'Advanced' }
                ]
            },
            'MeshPhysicalMaterial': {
                params: [
                    { name: 'color', label: '反照率', type: 'color', default: '#ffffff', category: 'Main', hasTexture: 'map' },
                    { name: 'metalness', label: '金属度', type: 'slider', min: 0, max: 1, step: 0.01, default: 0.5, category: 'Main', hasTexture: 'metalnessMap' },
                    { name: 'roughness', label: '粗糙度', type: 'slider', min: 0, max: 1, step: 0.01, default: 0.5, category: 'Main', hasTexture: 'roughnessMap' },
                    { name: 'normalMap', label: '法线贴图', type: 'texture', default: null, category: 'Maps' },
                    { name: 'bumpMap', label: '高度贴图', type: 'texture', default: null, category: 'Maps', hasIntensity: 'bumpScale' },
                    { name: 'aoMap', label: '遮挡贴图', type: 'texture', default: null, category: 'Maps', hasIntensity: 'aoIntensity' },
                    { name: 'clearcoat', label: '清漆', type: 'slider', min: 0, max: 1, step: 0.01, default: 0, category: 'Physical' },
                    { name: 'clearcoatRoughness', label: '清漆粗糙度', type: 'slider', min: 0, max: 1, step: 0.01, default: 0, category: 'Physical' },
                    { name: 'transmission', label: '透光率', type: 'slider', min: 0, max: 1, step: 0.01, default: 0, category: 'Physical' },
                    { name: 'emissive', label: '自发光', type: 'color', default: '#000000', category: 'Emission', hasTexture: 'emissiveMap', hasIntensity: 'emissiveIntensity' },
                    { name: 'opacity', label: '不透明度', type: 'slider', min: 0, max: 1, step: 0.01, default: 1.0, category: 'Advanced' }
                ]
            }
        };
    }
    
    /**
     * 根据材质类型渲染参数
     */
    renderParametersByType(materialType) {
        const container = document.getElementById('material-params-container');
        if (!container) return;
        
        const config = this.getMaterialTypeConfig()[materialType];
        if (!config) {
            console.error('未找到材质类型配置:', materialType);
            return;
        }
        
        // 按类别组织参数
        const categories = {};
        config.params.forEach(param => {
            const category = param.category || 'Main';
            if (!categories[category]) {
                categories[category] = [];
            }
            categories[category].push(param);
        });
        
        // 生成HTML
        let html = '';
        for (const [category, params] of Object.entries(categories)) {
            // 类别标题（如果不是Main）
            if (category !== 'Main' && params.length > 0) {
                html += `
                    <div class="param-category-divider">
                        <span>${category}</span>
                        </div>
                `;
            }
            
            // 渲染参数
            params.forEach(param => {
                const value = this.currentMaterialSettings?.[param.name] ?? param.default;
                html += this.renderParameter(param, value);
            });
        }
        
        container.innerHTML = html;
        
        // 重新绑定事件
        this.bindParameterEvents();
    }
    
    /**
     * 渲染单个参数（支持参数+贴图+强度在同一行）
     */
    renderParameter(param, value) {
        const paramId = `panel-mat-${param.name}`;
        
        // 颜色参数（可能带贴图）
        if (param.type === 'color') {
            const textureHtml = param.hasTexture ? this.renderTextureControl(param.hasTexture) : '';
            const intensityHtml = param.hasIntensity ? this.renderIntensityControl(param.hasIntensity) : '';
            
            return `
                <div class="param-row param-row-color" data-param="${param.name}">
                    <label>${param.label}</label>
                    <div class="param-controls">
                        <input type="color" id="${paramId}" value="${value}">
                        <input type="text" id="${paramId}-hex" value="${value}" class="param-hex-input">
                        ${textureHtml}
                        ${intensityHtml}
                    </div>
                </div>
            `;
        } 
        // 滑块参数（可能带贴图）
        else if (param.type === 'slider') {
            const textureHtml = param.hasTexture ? this.renderTextureControl(param.hasTexture) : '';
            
            return `
                <div class="param-row param-row-slider" data-param="${param.name}">
                    <label>${param.label}</label>
                    <div class="param-controls">
                        <input type="range" id="${paramId}" 
                               min="${param.min}" max="${param.max}" step="${param.step}" value="${value}">
                        <input type="number" id="${paramId}-value" 
                               min="${param.min}" max="${param.max}" step="${param.step}" value="${value}" 
                               class="param-value">
                        ${textureHtml}
                    </div>
                </div>
            `;
        } 
        // 独立贴图参数（法线、AO等）
        else if (param.type === 'texture') {
            const intensityHtml = param.hasIntensity ? this.renderIntensityControl(param.hasIntensity) : '';
            const textureHtml = this.renderTextureControl(param.name);
            
            return `
                <div class="param-row param-row-texture-only" data-param="${param.name}">
                    <label>${param.label}</label>
                    <div class="param-controls">
                        ${textureHtml}
                        ${intensityHtml}
                    </div>
                </div>
            `;
        }
        
        return '';
    }
    
    /**
     * 渲染贴图控件
     */
    renderTextureControl(textureName) {
        const hasTexture = this.checkTextureExists(textureName);
        const textureId = `panel-mat-${textureName}`;
        
        return `
            <label class="texture-btn ${hasTexture ? 'has-texture' : ''}" 
                   for="${textureId}-file" 
                   title="${hasTexture ? '已有贴图，点击更换' : '点击上传贴图'}"
                   data-texture="${textureName}">
                <span class="texture-icon">${hasTexture ? '🖼️' : '○'}</span>
            </label>
            <input type="file" 
                   id="${textureId}-file" 
                   accept="image/*" 
                   data-texture="${textureName}"
                   style="display: none;">
            ${hasTexture ? `<button class="texture-clear" id="${textureId}-remove" data-texture="${textureName}" title="移除贴图">×</button>` : ''}
        `;
    }
    
    /**
     * 渲染强度控件
     */
    renderIntensityControl(intensityName) {
        const intensityId = `panel-mat-${intensityName}`;
        const value = this.currentMaterialSettings?.[intensityName] ?? 1.0;
        
        // 根据强度类型设置范围
        let min = 0, max = 2, step = 0.01;
        if (intensityName === 'bumpScale') {
            min = 0; max = 1; step = 0.01;
        } else if (intensityName === 'emissiveIntensity') {
            min = 0; max = 2; step = 0.01;
        } else if (intensityName === 'aoIntensity') {
            min = 0; max = 2; step = 0.01;
        }
        
        return `
            <input type="number" 
                   id="${intensityId}-value" 
                   min="${min}" max="${max}" step="${step}" 
                   value="${value}" 
                   class="param-intensity"
                   title="强度"
                   placeholder="强度">
        `;
    }
    
    /**
     * 检查贴图是否存在
     */
    checkTextureExists(textureName) {
        // 检查当前节点的3D对象是否有贴图
        const node = window.transformPanel?.currentNode;
        if (node && node.object3D) {
            let hasTexture = false;
            node.object3D.traverse((child) => {
                if (child.isMesh && child.material) {
                    const mat = Array.isArray(child.material) ? child.material[0] : child.material;
                    if (mat && mat[textureName]) {
                        hasTexture = true;
                    }
                }
            });
            return hasTexture;
        }
        
        // 或者从材质设置中检查
        return this.currentMaterialSettings?.[`has${textureName.charAt(0).toUpperCase() + textureName.slice(1)}`] || false;
    }
    
    /**
     * 绑定参数事件（支持hasTexture和hasIntensity）
     */
    bindParameterEvents() {
        const config = this.getMaterialTypeConfig();
        const materialType = document.getElementById('material-type-select')?.value || 'MeshStandardMaterial';
        const typeConfig = config[materialType];
        
        if (!typeConfig) return;
        
        typeConfig.params.forEach(param => {
            const paramId = `panel-mat-${param.name}`;
            
            // 颜色参数
            if (param.type === 'color') {
                const colorInput = document.getElementById(paramId);
                const hexInput = document.getElementById(`${paramId}-hex`);
                
                if (colorInput && hexInput) {
                    colorInput.oninput = () => {
                        hexInput.value = colorInput.value;
                        const changes = {};
                        changes[param.name] = colorInput.value;
                        this.applyLiveUpdate(changes);
                    };
                    hexInput.oninput = () => {
                        if (/^#[0-9A-F]{6}$/i.test(hexInput.value)) {
                            colorInput.value = hexInput.value;
                            const changes = {};
                            changes[param.name] = hexInput.value;
                            this.applyLiveUpdate(changes);
                        }
                    };
                }
                
                // 绑定关联的贴图上传
                if (param.hasTexture) {
                    this.bindTextureControl(param.hasTexture);
                }
                
                // 绑定关联的强度控制
                if (param.hasIntensity) {
                    this.bindIntensityControl(param.hasIntensity);
                }
            } 
            // 滑块参数
            else if (param.type === 'slider') {
                const sliderInput = document.getElementById(paramId);
                const numberInput = document.getElementById(`${paramId}-value`);
                
                if (sliderInput && numberInput) {
                    sliderInput.oninput = () => {
                        numberInput.value = sliderInput.value;
                        const changes = {};
                        changes[param.name] = parseFloat(sliderInput.value);
                        this.applyLiveUpdate(changes);
                    };
                    numberInput.oninput = () => {
                        sliderInput.value = numberInput.value;
                        const changes = {};
                        changes[param.name] = parseFloat(numberInput.value);
                        this.applyLiveUpdate(changes);
                    };
                }
                
                // 绑定关联的贴图上传
                if (param.hasTexture) {
                    this.bindTextureControl(param.hasTexture);
                }
            } 
            // 独立贴图参数
            else if (param.type === 'texture') {
                this.bindTextureControl(param.name);
                
                // 绑定关联的强度控制
                if (param.hasIntensity) {
                    this.bindIntensityControl(param.hasIntensity);
                }
            }
        });
    }
    
    /**
     * 绑定贴图控件
     */
    bindTextureControl(textureName) {
        const textureId = `panel-mat-${textureName}`;
        
        // 绑定文件上传
        const fileInput = document.getElementById(`${textureId}-file`);
        if (fileInput) {
            fileInput.onchange = (e) => {
                this.handleTextureUpload(textureName, e.target.files[0]);
            };
        }
        
        // 绑定删除按钮
        const removeBtn = document.getElementById(`${textureId}-remove`);
        if (removeBtn) {
            removeBtn.onclick = (e) => {
                e.preventDefault();
                e.stopPropagation();
                this.handleTextureRemove(textureName);
            };
        }
    }
    
    /**
     * 绑定强度控件
     */
    bindIntensityControl(intensityName) {
        const intensityId = `panel-mat-${intensityName}`;
        const intensityInput = document.getElementById(`${intensityId}-value`);
        
        if (intensityInput) {
            intensityInput.oninput = () => {
                const changes = {};
                changes[intensityName] = parseFloat(intensityInput.value);
                this.applyLiveUpdate(changes);
            };
        }
    }
    
    /**
     * 处理贴图上传
     */
    async handleTextureUpload(textureName, file) {
        if (!file) return;
        try {
            // 1. 上传贴图到服务器
            const projectId = this.currentModel.projectId;
            const formData = new FormData();
            formData.append('texture', file);
            
            const uploadResponse = await fetch(`/api/projects/${projectId}/textures/upload`, {
                method: 'POST',
                body: formData
            });
            
            if (!uploadResponse.ok) {
                throw new Error('贴图上传失败');
            }
            
            const uploadResult = await uploadResponse.json();
            if (!uploadResult.success) {
                throw new Error(uploadResult.error || '贴图上传失败');
            }
            
            const textureData = uploadResult.data;
            // 2. 使用Three.js加载贴图
            const textureUrl = `http://localhost:7283${textureData.path}`;
            const textureLoader = new THREE.TextureLoader();
            const texture = await new Promise((resolve, reject) => {
                textureLoader.load(
                    textureUrl,
                    (tex) => resolve(tex),
                    undefined,
                    (error) => reject(error)
                );
            });
            // 3. 应用到场景中的材质
            const node = window.transformPanel?.currentNode;
            if (node && node.object3D) {
                node.object3D.traverse((child) => {
                    if (child.isMesh && child.material) {
                        const materials = Array.isArray(child.material) ? child.material : [child.material];
                        materials.forEach(mat => {
                            if (mat && mat[textureName] !== undefined) {
                                mat[textureName] = texture;
                                mat.needsUpdate = true;
                            }
                        });
                    }
                });
            }
            
            // 4. 保存贴图路径到当前材质设置
            if (!this.currentMaterialSettings) {
                this.currentMaterialSettings = {};
            }
            this.currentMaterialSettings[textureName] = textureData.path;
            this.currentMaterialSettings[`${textureName}Id`] = textureData.id;
            
            // 更新UI状态 - Unity风格（贴图按钮+图标）
            const textureId = `panel-mat-${textureName}`;
            const textureBtn = document.querySelector(`label[for="${textureId}-file"]`);
            if (textureBtn) {
                // 更新贴图按钮样式和图标
                textureBtn.classList.add('has-texture');
                const icon = textureBtn.querySelector('.texture-icon');
                if (icon) {
                    icon.textContent = '🖼️';
                }
                textureBtn.title = '已有贴图，点击更换';
                
                // 添加删除按钮（如果没有）
                const removeBtn = document.getElementById(`${textureId}-remove`);
                if (!removeBtn) {
                    const newRemoveBtn = document.createElement('button');
                    newRemoveBtn.id = `${textureId}-remove`;
                    newRemoveBtn.className = 'texture-clear';
                    newRemoveBtn.setAttribute('data-texture', textureName);
                    newRemoveBtn.textContent = '×';
                    newRemoveBtn.title = '移除贴图';
                    newRemoveBtn.onclick = (e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        this.handleTextureRemove(textureName);
                    };
                    textureBtn.parentElement.appendChild(newRemoveBtn);
                }
            }
            
            // 保存贴图标志到设置
            if (!this.currentMaterialSettings) {
                this.currentMaterialSettings = {};
            }
            this.currentMaterialSettings[`has${textureName.charAt(0).toUpperCase() + textureName.slice(1)}`] = true;
            
            if (window.showManageMessage) {
                window.showManageMessage(`贴图 "${textureName}" 已加载`, 'success');
            }
            
        } catch (error) {
            console.error(`❌ 加载贴图失败: ${textureName}`, error);
            if (window.showManageMessage) {
                window.showManageMessage(`加载贴图失败: ${error.message}`, 'error');
            }
        }
    }
    
    /**
     * 处理贴图移除
     */
    handleTextureRemove(textureName) {
        // 从场景中的材质移除
        const node = window.transformPanel?.currentNode;
        if (node && node.object3D) {
            node.object3D.traverse((child) => {
                if (child.isMesh && child.material) {
                    const materials = Array.isArray(child.material) ? child.material : [child.material];
                    materials.forEach(mat => {
                        if (mat && mat[textureName]) {
                            mat[textureName] = null;
                            mat.needsUpdate = true;
                        }
                    });
                }
            });
        }
        
        // 更新UI状态 - Unity风格（贴图按钮+图标）
        const textureId = `panel-mat-${textureName}`;
        const textureBtn = document.querySelector(`label[for="${textureId}-file"]`);
        if (textureBtn) {
            // 恢复贴图按钮样式和图标
            textureBtn.classList.remove('has-texture');
            const icon = textureBtn.querySelector('.texture-icon');
            if (icon) {
                icon.textContent = '○';
            }
            textureBtn.title = '点击上传贴图';
            
            // 移除删除按钮
            const removeBtn = document.getElementById(`${textureId}-remove`);
            if (removeBtn) {
                removeBtn.remove();
            }
        }
        
        // 更新设置
        if (this.currentMaterialSettings) {
            this.currentMaterialSettings[`has${textureName.charAt(0).toUpperCase() + textureName.slice(1)}`] = false;
        }
        
        if (window.showManageMessage) {
            window.showManageMessage(`贴图 "${textureName}" 已移除`, 'success');
        }
    }
    
    /**
     * 设置材质选择器
     */
    async setupMaterialSelector() {
        try {
            // 更新当前材质名称显示
            const currentNameInput = document.getElementById('material-current-name');
            if (currentNameInput && this.currentMaterial) {
                currentNameInput.value = this.currentMaterial.displayName || this.currentMaterial.name;
            }
        } catch (error) {
            console.error('❌ 设置材质选择器失败:', error);
        }
    }
    
    /**
     * 从下拉列表选择材质
     */
    async selectMaterialFromDropdown(materialId) {
        try {
            const material = await this.materialLibraryManager.getMaterial(materialId);
            if (!material) {
                console.error('❌ 材质不存在:', materialId);
                return;
            }
            
            this.currentMaterial = material;
            this.currentMaterialSettings = material;
            
            // 更新搜索输入框显示
            const searchInput = document.getElementById('material-search-input');
            if (searchInput) {
                searchInput.value = material.displayName || material.name;
            }
            
            // 应用材质到模型
            await this.materialLibraryManager.applyMaterialToModel(this.currentModel.id, materialId);
            
            // 更新面板显示的参数
            this.updatePanelFromMaterial(material);
            
            // 刷新场景中的材质
            await this.refreshSceneMaterials();
            
            if (window.showManageMessage) {
                window.showManageMessage(`已应用材质：${material.displayName || material.name}`, 'success');
            }
        } catch (error) {
            console.error('❌ 选择材质失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('选择材质失败: ' + error.message, 'error');
            }
        }
    }
    
    /**
     * 根据材质更新面板参数（新版本 - 与动态参数系统兼容）
     */
    updatePanelFromMaterial(material) {
        // 更新 currentMaterialSettings
        this.currentMaterialSettings = { ...material };
        
        // 更新材质类型选择器
        const materialTypeSelect = document.getElementById('material-type-select');
        if (materialTypeSelect) {
            const materialType = material.materialType || 'MeshStandardMaterial';
            materialTypeSelect.value = materialType;
            this.updateMaterialTypeHint(materialType);
            
            // 重新渲染参数
            this.renderParametersByType(materialType);
        }
        
        // 不再需要手动更新每个参数，因为 renderParametersByType 会从 this.currentMaterialSettings 读取值
    }
    
    /**
     * 绑定面板事件（实时预览）
     */
    bindPanelEvents() {
        // 基础颜色
        const colorInput = document.getElementById('panel-mat-color');
        const colorHex = document.getElementById('panel-mat-color-hex');
        if (colorInput && colorHex) {
            colorInput.oninput = () => {
                colorHex.value = colorInput.value;
                this.applyLiveUpdate({ color: colorInput.value });
            };
            colorHex.oninput = () => {
                if (/^#[0-9A-F]{6}$/i.test(colorHex.value)) {
                    colorInput.value = colorHex.value;
                    this.applyLiveUpdate({ color: colorHex.value });
                }
            };
        }
        
        // 金属度
        const metalnessInput = document.getElementById('panel-mat-metalness');
        const metalnessValue = document.getElementById('panel-metalness-value');
        if (metalnessInput && metalnessValue) {
            metalnessInput.oninput = () => {
                metalnessValue.value = metalnessInput.value;
                this.applyLiveUpdate({ metalness: parseFloat(metalnessInput.value) });
            };
            metalnessValue.oninput = () => {
                metalnessInput.value = metalnessValue.value;
                this.applyLiveUpdate({ metalness: parseFloat(metalnessValue.value) });
            };
        }
        
        // 粗糙度
        const roughnessInput = document.getElementById('panel-mat-roughness');
        const roughnessValue = document.getElementById('panel-roughness-value');
        if (roughnessInput && roughnessValue) {
            roughnessInput.oninput = () => {
                roughnessValue.value = roughnessInput.value;
                this.applyLiveUpdate({ roughness: parseFloat(roughnessInput.value) });
            };
            roughnessValue.oninput = () => {
                roughnessInput.value = roughnessValue.value;
                this.applyLiveUpdate({ roughness: parseFloat(roughnessValue.value) });
            };
        }
        
        // AO强度
        const aoInput = document.getElementById('panel-mat-ao-intensity');
        const aoValue = document.getElementById('panel-ao-intensity-value');
        if (aoInput && aoValue) {
            aoInput.oninput = () => {
                aoValue.value = aoInput.value;
                this.applyLiveUpdate({ aoIntensity: parseFloat(aoInput.value) });
            };
            aoValue.oninput = () => {
                aoInput.value = aoValue.value;
                this.applyLiveUpdate({ aoIntensity: parseFloat(aoValue.value) });
            };
        }
        
        // 凹凸强度
        const bumpInput = document.getElementById('panel-mat-bump-scale');
        const bumpValue = document.getElementById('panel-bump-scale-value');
        if (bumpInput && bumpValue) {
            bumpInput.oninput = () => {
                bumpValue.value = bumpInput.value;
                this.applyLiveUpdate({ bumpScale: parseFloat(bumpInput.value) });
            };
            bumpValue.oninput = () => {
                bumpInput.value = bumpValue.value;
                this.applyLiveUpdate({ bumpScale: parseFloat(bumpValue.value) });
            };
        }
        
        // 发光颜色
        const emissiveInput = document.getElementById('panel-mat-emissive');
        const emissiveHex = document.getElementById('panel-mat-emissive-hex');
        if (emissiveInput && emissiveHex) {
            emissiveInput.oninput = () => {
                emissiveHex.value = emissiveInput.value;
                this.applyLiveUpdate({ emissive: emissiveInput.value });
            };
            emissiveHex.oninput = () => {
                if (/^#[0-9A-F]{6}$/i.test(emissiveHex.value)) {
                    emissiveInput.value = emissiveHex.value;
                    this.applyLiveUpdate({ emissive: emissiveHex.value });
                }
            };
        }
        
        // 发光强度
        const emissiveIntensityInput = document.getElementById('panel-mat-emissive-intensity');
        const emissiveIntensityValue = document.getElementById('panel-emissive-intensity-value');
        if (emissiveIntensityInput && emissiveIntensityValue) {
            emissiveIntensityInput.oninput = () => {
                emissiveIntensityValue.value = emissiveIntensityInput.value;
                this.applyLiveUpdate({ emissiveIntensity: parseFloat(emissiveIntensityInput.value) });
            };
            emissiveIntensityValue.oninput = () => {
                emissiveIntensityInput.value = emissiveIntensityValue.value;
                this.applyLiveUpdate({ emissiveIntensity: parseFloat(emissiveIntensityValue.value) });
            };
        }
    }
    
    /**
     * 根据类型创建材质
     */
    createMaterialByType(materialType, sourceMat) {
        const baseProps = {
            color: sourceMat.color ? sourceMat.color.clone() : new THREE.Color(0xffffff),
            map: sourceMat.map || null,
            opacity: sourceMat.opacity !== undefined ? sourceMat.opacity : 1.0,
            transparent: sourceMat.transparent || false,
            side: sourceMat.side !== undefined ? sourceMat.side : THREE.FrontSide
        };
        
        let newMat;
        
        switch(materialType) {
            case 'MeshStandardMaterial':
                newMat = new THREE.MeshStandardMaterial({
                    ...baseProps,
                    normalMap: sourceMat.normalMap || null,
                    emissive: sourceMat.emissive ? sourceMat.emissive.clone() : new THREE.Color(0x000000),
                    emissiveIntensity: sourceMat.emissiveIntensity || 0,
                    emissiveMap: sourceMat.emissiveMap || null,
                    metalness: this.currentMaterialSettings?.metalness ?? sourceMat.metalness ?? 0.5,
                    roughness: this.currentMaterialSettings?.roughness ?? sourceMat.roughness ?? 0.5,
                    aoMapIntensity: this.currentMaterialSettings?.aoIntensity ?? sourceMat.aoMapIntensity ?? 1.0,
                    bumpScale: this.currentMaterialSettings?.bumpScale ?? sourceMat.bumpScale ?? 0
                });
                break;
                
            case 'MeshPhongMaterial':
                newMat = new THREE.MeshPhongMaterial({
                    ...baseProps,
                    emissive: sourceMat.emissive ? sourceMat.emissive.clone() : new THREE.Color(0x000000),
                    emissiveIntensity: this.currentMaterialSettings?.emissiveIntensity ?? sourceMat.emissiveIntensity ?? 0,
                    specular: sourceMat.specular ? sourceMat.specular.clone() : new THREE.Color(0x111111),
                    shininess: this.currentMaterialSettings?.shininess ?? sourceMat.shininess ?? 30
                });
                break;
                
            case 'MeshLambertMaterial':
                newMat = new THREE.MeshLambertMaterial({
                    ...baseProps,
                    emissive: sourceMat.emissive ? sourceMat.emissive.clone() : new THREE.Color(0x000000),
                    emissiveIntensity: this.currentMaterialSettings?.emissiveIntensity ?? sourceMat.emissiveIntensity ?? 0
                });
                break;
                
            case 'MeshBasicMaterial':
                newMat = new THREE.MeshBasicMaterial(baseProps);
                break;
                
            case 'MeshPhysicalMaterial':
                newMat = new THREE.MeshPhysicalMaterial({
                    ...baseProps,
                    normalMap: sourceMat.normalMap || null,
                    emissive: sourceMat.emissive ? sourceMat.emissive.clone() : new THREE.Color(0x000000),
                    emissiveIntensity: this.currentMaterialSettings?.emissiveIntensity ?? sourceMat.emissiveIntensity ?? 0,
                    emissiveMap: sourceMat.emissiveMap || null,
                    metalness: this.currentMaterialSettings?.metalness ?? sourceMat.metalness ?? 0.5,
                    roughness: this.currentMaterialSettings?.roughness ?? sourceMat.roughness ?? 0.5,
                    clearcoat: this.currentMaterialSettings?.clearcoat ?? sourceMat.clearcoat ?? 0,
                    clearcoatRoughness: this.currentMaterialSettings?.clearcoatRoughness ?? sourceMat.clearcoatRoughness ?? 0,
                    transmission: this.currentMaterialSettings?.transmission ?? sourceMat.transmission ?? 0,
                    aoMapIntensity: this.currentMaterialSettings?.aoIntensity ?? sourceMat.aoMapIntensity ?? 1.0,
                    bumpScale: this.currentMaterialSettings?.bumpScale ?? sourceMat.bumpScale ?? 0
                });
                break;
                
            default:
                console.warn(`未知材质类型: ${materialType}，使用 MeshStandardMaterial`);
                newMat = new THREE.MeshStandardMaterial(baseProps);
        }
        
        return newMat;
    }
    
    /**
     * 实时应用材质更新到场景
     */
    applyLiveUpdate(changes) {
        // 更新 currentMaterialSettings
        if (!this.currentMaterialSettings) {
            this.currentMaterialSettings = {};
        }
        Object.assign(this.currentMaterialSettings, changes);
        
        // 找到当前模型的所有节点
        const node = window.transformPanel?.currentNode;
        if (!node || !node.object3D) return;
        // 获取目标材质类型
        const materialTypeSelect = document.getElementById('material-type-select');
        const targetMaterialType = materialTypeSelect?.value || 'MeshStandardMaterial';
        
        // 直接应用到场景中的材质
        node.object3D.traverse((child) => {
            if (child.isMesh && child.material) {
                const materials = Array.isArray(child.material) ? child.material : [child.material];
                materials.forEach((mat, index) => {
                    if (!mat) return;
                    
                    // ✅ 如果材质类型不匹配，转换材质类型
                    if (mat.type !== targetMaterialType) {
                        const newMat = this.createMaterialByType(targetMaterialType, mat);
                        
                        // 替换材质
                        if (Array.isArray(child.material)) {
                            child.material[index] = newMat;
                            mat = child.material[index];
                        } else {
                            child.material = newMat;
                            mat = child.material;
                        }
                    }
                    
                        // 应用变化
                    if (mat.color && changes.color !== undefined) {
                            mat.color.set(changes.color);
                        }
                    
                    // PBR 材质属性 (MeshStandardMaterial, MeshPhysicalMaterial)
                        if (changes.metalness !== undefined && mat.metalness !== undefined) {
                            mat.metalness = changes.metalness;
                        }
                        if (changes.roughness !== undefined && mat.roughness !== undefined) {
                            mat.roughness = changes.roughness;
                    }
                    
                    // Phong 材质属性
                    if (changes.specular !== undefined && mat.specular) {
                        mat.specular.set(changes.specular);
                    }
                    if (changes.shininess !== undefined && mat.shininess !== undefined) {
                        mat.shininess = changes.shininess;
                    }
                    
                    // Physical 材质属性
                    if (changes.clearcoat !== undefined && mat.clearcoat !== undefined) {
                        mat.clearcoat = changes.clearcoat;
                    }
                    if (changes.clearcoatRoughness !== undefined && mat.clearcoatRoughness !== undefined) {
                        mat.clearcoatRoughness = changes.clearcoatRoughness;
                    }
                    if (changes.transmission !== undefined && mat.transmission !== undefined) {
                        mat.transmission = changes.transmission;
                    }
                    
                    // 通用属性
                        if (changes.aoIntensity !== undefined && mat.aoMapIntensity !== undefined) {
                            mat.aoMapIntensity = changes.aoIntensity;
                        }
                        if (changes.bumpScale !== undefined && mat.bumpScale !== undefined) {
                            mat.bumpScale = changes.bumpScale;
                        }
                        if (changes.emissive !== undefined && mat.emissive) {
                            mat.emissive.set(changes.emissive);
                        }
                        if (changes.emissiveIntensity !== undefined && mat.emissiveIntensity !== undefined) {
                            mat.emissiveIntensity = changes.emissiveIntensity;
                    }
                    if (changes.opacity !== undefined && mat.opacity !== undefined) {
                        mat.opacity = changes.opacity;
                        // 🔧 修复：如果有贴图或opacity<1，都需要开启transparent
                        mat.transparent = changes.opacity < 1.0 || !!mat.map || !!mat.alphaMap;
                    }
                    
                    // 🎯 透明度控制参数（解决透明贴图遮挡问题）
                    if (changes.alphaTest !== undefined) {
                        mat.alphaTest = changes.alphaTest;
                    }
                    
                    // 🎯 深度写入控制（关键！解决透明区域遮挡后面物体的问题）
                    if (changes.depthWrite !== undefined) {
                        mat.depthWrite = changes.depthWrite;
                    }
                    
                    // 🎯 【最终修复】自动检测并修复透明材质问题
                    // 这个逻辑确保：无论何时材质被更新，都能正确处理透明度
                    if (mat.alphaMap || mat.transparent || mat.opacity < 1.0) {
                        // 确保启用透明度
                        if (!mat.transparent) {
                            mat.transparent = true;
                            console.log(`   🔧 [自动修复] 启用透明度: transparent = true`);
                        }
                        
                        // 如果有 alphaMap 但没有设置 alphaTest，设置默认值
                        if (mat.alphaMap && (mat.alphaTest === undefined || mat.alphaTest === 0)) {
                            mat.alphaTest = 0.5;
                            console.log(`   🔧 [自动修复] 设置 alphaTest = 0.5`);
                        }
                        
                        // 🔑 关键修复：确保禁用深度写入
                        if (mat.depthWrite !== false) {
                            mat.depthWrite = false;
                            console.log(`   🔧 [自动修复] 禁用深度写入: depthWrite = false`);
                        }
                    }
                        
                    mat.needsUpdate = true;
                });
            }
        });
    }
    
    /**
     * 从面板收集材质设置
     */
    collectPanelSettings() {
        return {
            materialType: document.getElementById('material-type-select')?.value || 'MeshStandardMaterial',
            color: document.getElementById('panel-mat-color')?.value || '#ffffff',
            metalness: parseFloat(document.getElementById('panel-mat-metalness')?.value || 0.5),
            roughness: parseFloat(document.getElementById('panel-mat-roughness')?.value || 0.5),
            emissive: document.getElementById('panel-mat-emissive')?.value || '#000000',
            emissiveIntensity: parseFloat(document.getElementById('panel-mat-emissive-intensity')?.value || 0),
            aoIntensity: parseFloat(document.getElementById('panel-mat-ao-intensity')?.value || 1.0),
            bumpScale: parseFloat(document.getElementById('panel-mat-bump-scale')?.value || 0.0),
            opacity: 1.0,
            doubleSided: false
        };
    }
    
    /**
     * 从面板保存材质
     */
    async saveFromPanel() {
        try {
            const settings = this.collectPanelSettings();
            // ✅ 如果有 currentMaterial，保存到材质库
            if (this.currentMaterial && this.currentMaterial.id) {
                // 更新材质库中的材质
                await this.materialLibraryManager.updateMaterial(this.currentMaterial.id, settings);
            } else {
                // ✅ 降级：保存到旧的 model.material 字段
                const response = await fetch(
                    `/api/projects/${this.currentModel.projectId}/models/${this.currentModel.id}/material`,
                    {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(settings)
                    }
                );
                
                const result = await response.json();
                
                if (!result.success) {
                    throw new Error(result.error || '保存失败');
                }
            }
            // ✅ 刷新场景中使用该模型的所有节点的材质
            await this.refreshSceneMaterials();
            
            if (window.showManageMessage) {
                window.showManageMessage('材质已保存并应用！', 'success');
            }
            
        } catch (error) {
            console.error('❌ 保存材质设置失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('保存失败: ' + error.message, 'error');
            }
        }
    }
    
    /**
     * 打开材质编辑器（旧的 modal 模式，保留向后兼容）
     * @param {Object} modelData - 模型数据
     */
    async open(modelData) {
        // 使用新的面板模式
        return this.openInPanel(modelData);
    }
    
    /**
     * 显示创建材质对话框
     */
    async showCreateMaterialDialog(modelData) {
        return new Promise((resolve) => {
            const dialog = document.createElement('div');
            dialog.className = 'modal-overlay';
            dialog.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.75);
                backdrop-filter: blur(5px);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 100000;
            `;
            
            dialog.innerHTML = `
                <div class="modal-content" style="max-width: 500px;">
                    <div class="modal-header">
                        <h3>🎨 该模型使用自带材质</h3>
                    </div>
                    <div class="modal-body">
                        <p style="line-height: 1.8; color: rgba(255,255,255,0.8);">
                            模型 <strong>"${modelData.name}"</strong> 当前使用的是导入时的自带材质。
                        </p>
                        <p style="line-height: 1.8; color: rgba(255,255,255,0.8);">
                            自带材质无法直接修改。是否要<strong>创建一个新材质</strong>来编辑此模型的材质属性？
                        </p>
                        <div style="background: rgba(102, 126, 234, 0.1); border-left: 3px solid #667eea; padding: 12px; margin-top: 15px; border-radius: 4px;">
                            <p style="margin: 0; font-size: 13px; color: rgba(255,255,255,0.7);">
                                💡 <strong>提示：</strong>新材质将复制当前的材质参数，并可以保存到材质库中供其他模型使用。
                            </p>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button class="modal-btn modal-btn-secondary" id="cancel-create-material">取消</button>
                        <button class="modal-btn modal-btn-primary" id="confirm-create-material">创建新材质</button>
                    </div>
                </div>
            `;
            
            document.body.appendChild(dialog);
            
            document.getElementById('cancel-create-material').onclick = () => {
                dialog.remove();
                resolve(false);
            };
            
            document.getElementById('confirm-create-material').onclick = () => {
                dialog.remove();
                resolve(true);
            };
            
            // 点击背景关闭
            dialog.onclick = (e) => {
                if (e.target === dialog) {
                    dialog.remove();
                    resolve(false);
                }
            };
        });
    }
    
    /**
     * 从模型自带材质创建新材质
     */
    async createMaterialFromBuiltIn(modelData) {
        // 生成材质名称
        const materialName = `material_${modelData.name.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase()}_${Date.now()}`;
        const materialDisplayName = `${modelData.name}的材质`;
        
        // 获取模型当前的材质参数（从3D对象读取）
        let currentMaterialParams = this.getDefaultMaterialParams();
        
        // 如果模型有旧的material字段，使用它
        if (modelData.material) {
            currentMaterialParams = { ...currentMaterialParams, ...modelData.material };
        }
        
        // 创建新材质
        const newMaterial = await this.materialLibraryManager.createMaterial({
            name: materialName,
            displayName: materialDisplayName,
            description: `从模型 ${modelData.name} 的自带材质创建`,
            ...currentMaterialParams
        });
        // 应用材质到模型
        await this.materialLibraryManager.applyMaterialToModel(modelData.id, newMaterial.id);
        if (window.showManageMessage) {
            window.showManageMessage('新材质已创建并应用到模型', 'success');
        }
        
        return newMaterial;
    }
    
    /**
     * 加载材质库列表
     */
    async loadMaterialLibrary() {
        try {
            const materials = await this.materialLibraryManager.loadMaterials();
            this.materials = materials;
            // 渲染材质列表
            this.renderMaterialList();
            
        } catch (error) {
            console.error('❌ 加载材质库失败:', error);
        }
    }
    
    /**
     * 渲染材质列表
     */
    renderMaterialList() {
        const listContainer = document.getElementById('material-library-list');
        
        if (!listContainer) {
            console.warn('⚠️ 材质列表容器不存在');
            return;
        }
        
        if (this.materials.length === 0) {
            listContainer.innerHTML = `
                <div class="material-list-empty">
                    <p>📦 材质库为空</p>
                    <p style="font-size: 12px; color: rgba(255,255,255,0.5);">点击"+ 新建材质"创建第一个材质</p>
                </div>
            `;
            return;
        }
        
        listContainer.innerHTML = this.materials.map(material => `
            <div class="material-list-item ${this.currentMaterial?.id === material.id ? 'active' : ''}" 
                 data-material-id="${material.id}"
                 onclick="window.getMaterialEditor().selectMaterial('${material.id}')">
                <div class="material-item-icon">🎨</div>
                <div class="material-item-info">
                    <div class="material-item-name">${material.displayName}</div>
                    <div class="material-item-meta">${material.name}</div>
                </div>
            </div>
        `).join('');
    }
    
    /**
     * 选择材质
     */
    async selectMaterial(materialId) {
        try {
            const material = await this.materialLibraryManager.getMaterial(materialId);
            this.currentMaterial = material;
            // 更新UI选中状态
            document.querySelectorAll('.material-list-item').forEach(item => {
                if (item.dataset.materialId === materialId) {
                    item.classList.add('active');
                } else {
                    item.classList.remove('active');
                }
            });
            
            // 应用材质到UI
            this.applySettingsToUI(material);
            
            // 更新预览
            this.updatePreview();
            
            // 启用操作按钮
            document.getElementById('btn-rename-material').disabled = false;
            document.getElementById('btn-duplicate-material').disabled = false;
            document.getElementById('btn-delete-material').disabled = false;
            
        } catch (error) {
            console.error('❌ 选择材质失败:', error);
        }
    }
    
    /**
     * 获取默认材质参数
     */
    getDefaultMaterialParams() {
        return {
            materialType: 'MeshStandardMaterial',
            color: '#ffffff',
            metalness: 0.5,
            roughness: 0.5,
            emissive: '#000000',
            emissiveIntensity: 0,
            opacity: 1.0,
            aoIntensity: 1.0,
            bumpScale: 0.0,
            doubleSided: false,
            map: null,
            normalMap: null,
            bumpMap: null,
            aoMap: null,
            roughnessMap: null,
            metalnessMap: null
        };
    }
    
    /**
     * 加载材质设置
     */
    async loadMaterialSettings(modelData) {
        try {
            // ✅ 优先从材质库加载（如果模型有 materialId）
            if (modelData.materialId) {
                const material = await this.materialLibraryManager.getMaterial(modelData.materialId);
                
                if (material) {
                    this.currentMaterial = material;
                    this.currentMaterialSettings = material;
                    
                    // 更新UI选中状态
                    document.querySelectorAll('.material-list-item').forEach(item => {
                        if (item.dataset.materialId === modelData.materialId) {
                            item.classList.add('active');
                        } else {
                            item.classList.remove('active');
                        }
                    });
                    
                    // 启用操作按钮
                    document.getElementById('btn-rename-material').disabled = false;
                    document.getElementById('btn-duplicate-material').disabled = false;
                    document.getElementById('btn-delete-material').disabled = false;
                    // 注意：不在这里应用到UI，因为DOM元素可能还未渲染
                    // renderParametersByType 会从 this.currentMaterialSettings 读取值
                    return;
                }
            }
            
            // ✅ 降级：从旧的 model.material 字段加载
            const response = await fetch(`/api/projects/${modelData.projectId}/models/${modelData.id}/material`);
            const result = await response.json();
            
            if (result.success && result.data) {
                this.currentMaterialSettings = result.data;
            } else {
                // 使用默认材质设置
                this.currentMaterialSettings = this.getDefaultMaterialSettings();
            }
        } catch (error) {
            console.warn('⚠️ 加载材质设置失败，使用默认值:', error);
            this.currentMaterialSettings = this.getDefaultMaterialSettings();
        }
        
        // 注意：不在这里应用到UI，因为DOM元素可能还未渲染
        // renderParametersByType 会从 this.currentMaterialSettings 读取值
    }
    
    /**
     * 获取默认材质设置
     */
    getDefaultMaterialSettings() {
        return {
            color: '#ffffff',
            metalness: 0.5,
            roughness: 0.5,
            emissive: '#000000',
            emissiveIntensity: 0,
            opacity: 1.0,
            aoIntensity: 1.0,
            doubleSided: false,
            // 贴图路径
            map: null,
            normalMap: null,
            aoMap: null,
            roughnessMap: null,
            metalnessMap: null
        };
    }
    
    /**
     * 应用设置到UI（新版本 - 与动态参数系统兼容）
     */
    applySettingsToUI(settings) {
        // 更新 currentMaterialSettings
        this.currentMaterialSettings = settings;
        
        // 更新材质类型选择器
        const materialTypeSelect = document.getElementById('material-type-select');
        if (materialTypeSelect && settings.materialType) {
            materialTypeSelect.value = settings.materialType;
            this.updateMaterialTypeHint(settings.materialType);
        }
        
        // 重新渲染参数（如果面板已经打开）
        const materialType = settings.materialType || 'MeshStandardMaterial';
        if (document.getElementById('material-params-container')) {
            this.renderParametersByType(materialType);
        }
    }
    
    /**
     * 从UI收集当前设置（新版本 - 直接返回 currentMaterialSettings，包含贴图）
     */
    collectSettingsFromUI() {
        // 在新系统中，所有参数变化都实时更新到 this.currentMaterialSettings
        // currentMaterialSettings 已经包含贴图路径和ID
        const settings = { ...this.currentMaterialSettings };
        
        // 收集所有贴图信息
        const textureProps = ['map', 'normalMap', 'bumpMap', 'aoMap', 'emissiveMap', 'metalnessMap', 'roughnessMap', 'specularMap'];
        settings.textures = {};
        
        textureProps.forEach(prop => {
            if (settings[prop]) {
                settings.textures[prop] = {
                    path: settings[prop],
                    id: settings[`${prop}Id`]
                };
            }
        });
        
        // 🔧 收集深度控制参数
        const polygonOffsetCheckbox = document.getElementById('mat-polygon-offset');
        const polygonOffsetFactorInput = document.getElementById('mat-polygon-offset-factor');
        const polygonOffsetUnitsInput = document.getElementById('mat-polygon-offset-units');
        const depthTestCheckbox = document.getElementById('mat-depth-test');
        const depthWriteCheckbox = document.getElementById('mat-depth-write');
        
        if (polygonOffsetCheckbox) {
            settings.polygonOffset = polygonOffsetCheckbox.checked;
        }
        if (polygonOffsetFactorInput) {
            settings.polygonOffsetFactor = parseFloat(polygonOffsetFactorInput.value) || 0;
        }
        if (polygonOffsetUnitsInput) {
            settings.polygonOffsetUnits = parseFloat(polygonOffsetUnitsInput.value) || 0;
        }
        if (depthTestCheckbox) {
            settings.depthTest = depthTestCheckbox.checked;
        }
        if (depthWriteCheckbox) {
            settings.depthWrite = depthWriteCheckbox.checked;
        }
        
        return settings;
    }
    
    /**
     * 初始化预览场景
     */
    initPreview() {
        const container = document.getElementById('material-preview-canvas');
        
        // 清理旧的场景
        if (this.previewRenderer) {
            container.removeChild(this.previewRenderer.domElement);
            this.previewRenderer.dispose();
        }
        
        // 创建场景
        this.previewScene = new THREE.Scene();
        this.previewScene.background = new THREE.Color(0x1a1a1a);
        
        // 创建相机
        this.previewCamera = new THREE.PerspectiveCamera(
            50,
            container.clientWidth / container.clientHeight,
            0.01,
            1000
        );
        this.previewCamera.position.set(3, 2, 3);
        this.previewCamera.lookAt(0, 0, 0);
        
        // 创建渲染器
        this.previewRenderer = new THREE.WebGLRenderer({ antialias: true });
        this.previewRenderer.setSize(container.clientWidth, container.clientHeight);
        this.previewRenderer.setPixelRatio(window.devicePixelRatio);
        container.appendChild(this.previewRenderer.domElement);
        
        // 添加灯光
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        this.previewScene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(5, 5, 5);
        this.previewScene.add(directionalLight);
        
        // 添加背面补光
        const backLight = new THREE.DirectionalLight(0xffffff, 0.3);
        backLight.position.set(-5, 3, -5);
        this.previewScene.add(backLight);
        
        // 添加网格辅助
        const gridHelper = new THREE.GridHelper(10, 10, 0x444444, 0x222222);
        this.previewScene.add(gridHelper);
        
        // 启动渲染循环
        this.startPreviewAnimation();
    }
    
    /**
     * 加载模型预览
     */
    async loadModelPreview(modelData) {
        // TODO: 加载实际的模型
        // 这里先用一个简单的几何体代替
        const geometry = new THREE.SphereGeometry(1, 64, 64);
        const material = new THREE.MeshStandardMaterial();
        
        this.previewMesh = new THREE.Mesh(geometry, material);
        this.previewScene.add(this.previewMesh);
        
        // 应用当前材质设置
        this.updatePreview();
    }
    
    /**
     * 更新预览
     */
    updatePreview() {
        if (!this.previewMesh) return;
        
        const settings = this.collectSettingsFromUI();
        const material = this.previewMesh.material;
        
        // 应用基础参数
        material.color.set(settings.color);
        material.metalness = settings.metalness;
        material.roughness = settings.roughness;
        material.emissive.set(settings.emissive);
        material.emissiveIntensity = settings.emissiveIntensity;
        material.opacity = settings.opacity;
        material.transparent = settings.opacity < 1.0;
        material.side = settings.doubleSided ? THREE.DoubleSide : THREE.FrontSide;
        
        // AO强度
        material.aoMapIntensity = settings.aoIntensity;
        
        // 🔧 应用深度控制参数
        if (settings.polygonOffset !== undefined) {
            material.polygonOffset = settings.polygonOffset;
        }
        if (settings.polygonOffsetFactor !== undefined) {
            material.polygonOffsetFactor = settings.polygonOffsetFactor;
        }
        if (settings.polygonOffsetUnits !== undefined) {
            material.polygonOffsetUnits = settings.polygonOffsetUnits;
        }
        if (settings.depthTest !== undefined) {
            material.depthTest = settings.depthTest;
        }
        if (settings.depthWrite !== undefined) {
            material.depthWrite = settings.depthWrite;
        }
        
        // 🎯 【最终修复】自动检测并修复透明材质问题
        if (material.alphaMap || material.transparent || material.opacity < 1.0) {
            if (!material.transparent) {
                material.transparent = true;
            }
            if (material.alphaMap && (material.alphaTest === undefined || material.alphaTest === 0)) {
                material.alphaTest = settings.alphaTest || 0.5;
            }
            if (material.depthWrite !== false && settings.depthWrite === undefined) {
                material.depthWrite = false;
            }
        }
        
        material.needsUpdate = true;
    }
    
    /**
     * 启动预览动画
     */
    startPreviewAnimation() {
        const animate = () => {
            this.animationId = requestAnimationFrame(animate);
            
            // 旋转预览模型
            if (this.previewMesh) {
                this.previewMesh.rotation.y += 0.005;
            }
            
            this.previewRenderer.render(this.previewScene, this.previewCamera);
        };
        
        animate();
    }
    
    /**
     * 停止预览动画
     */
    stopPreviewAnimation() {
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
    }
    
    /**
     * 重置相机
     */
    resetCamera() {
        if (this.previewCamera) {
            this.previewCamera.position.set(3, 2, 3);
            this.previewCamera.lookAt(0, 0, 0);
        }
    }
    
    /**
     * 重置材质
     */
    resetMaterial() {
        const defaultSettings = this.getDefaultMaterialSettings();
        this.applySettingsToUI(defaultSettings);
        this.updatePreview();
    }
    
    /**
     * 保存材质设置
     */
    async save() {
        try {
            const settings = this.collectSettingsFromUI();
            // ✅ 如果有 currentMaterial，保存到材质库
            if (this.currentMaterial && this.currentMaterial.id) {
                // 更新贴图引用计数
                await this.updateTextureReferences(this.currentMaterial.id, settings.textures || {});
                
                // 更新材质库中的材质
                await this.materialLibraryManager.updateMaterial(this.currentMaterial.id, settings);
                // 刷新材质库列表
                await this.loadMaterialLibrary();
                
            } else {
                // ✅ 降级：保存到旧的 model.material 字段
                const response = await fetch(
                    `/api/projects/${this.currentModel.projectId}/models/${this.currentModel.id}/material`,
                    {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(settings)
                    }
                );
                
                const result = await response.json();
                
                if (!result.success) {
                    throw new Error(result.error || '保存失败');
                }
            }
            // ✅ 刷新场景中使用该模型的所有节点的材质
            await this.refreshSceneMaterials();
            
            if (window.showManageMessage) {
                window.showManageMessage('材质设置已保存并应用到场景！', 'success');
            }
            this.close();
            
        } catch (error) {
            console.error('❌ 保存材质设置失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('保存失败: ' + error.message, 'error');
            }
        }
    }
    
    /**
     * 更新贴图引用计数
     */
    async updateTextureReferences(materialId, newTextures) {
        try {
            const projectId = this.currentModel.projectId;
            
            // 获取旧的贴图引用
            const oldTextures = this.currentMaterial.textures || {};
            
            // 找出新增的贴图
            for (const [key, textureInfo] of Object.entries(newTextures)) {
                if (textureInfo && textureInfo.id && !oldTextures[key]) {
                    // 新增引用
                    await fetch(`/api/projects/${projectId}/textures/${textureInfo.id}/add-reference`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ materialId })
                    });
                }
            }
            
            // 找出移除的贴图
            for (const [key, textureInfo] of Object.entries(oldTextures)) {
                if (textureInfo && textureInfo.id && !newTextures[key]) {
                    // 移除引用
                    await fetch(`/api/projects/${projectId}/textures/${textureInfo.id}/remove-reference`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ materialId })
                    });
                }
            }
            
        } catch (error) {
            console.error('❌ 更新贴图引用计数失败:', error);
            // 不抛出错误，避免影响材质保存
        }
    }
    
    /**
     * 刷新场景中的材质
     */
    async refreshSceneMaterials() {
        try {
            // 获取场景树管理器
            const sceneTreeManager = window.sceneTreeManager;
            if (!sceneTreeManager) {
                console.warn('⚠️ 场景树管理器不存在，无法刷新材质');
                return;
            }
            
            // 获取模型加载器
            const modelLoader = window.modelLoader;
            if (!modelLoader) {
                console.warn('⚠️ 模型加载器不存在，无法刷新材质');
                return;
            }
            
            // 查找所有使用该模型的节点
            const allNodes = sceneTreeManager.getAllNodes();
            const affectedNodes = allNodes.filter(node => {
                // 从 components 中获取 modelId，或直接从 node.modelId
                const modelComponent = node.components?.find(c => c.type === 'model');
                const nodeModelId = modelComponent?.modelId || node.modelId;
                
                // 先输出日志，再进行过滤判断
                // ✅ 修复：不检查 node.type，而是检查是否有模型组件
                if (!modelComponent) {
                    return false;
                }
                
                // 检查 modelId 是否匹配
                if (nodeModelId === this.currentModel.id) {
                    return true;
                } else {
                    return false;
                }
            });
            if (affectedNodes.length === 0) {
                console.warn('⚠️ 未找到使用该模型的节点');
                return;
            }
            
            // 重新加载每个节点的材质
            for (const node of affectedNodes) {
                if (node.object3D) {
                    await modelLoader.applyMaterialSettings(
                        node.object3D,
                        this.currentModel.projectId,
                        this.currentModel.id
                    );
                } else {
                    console.warn(`⚠️ 节点 "${node.name}" 没有 object3D`);
                }
            }
        } catch (error) {
            console.error('❌ 刷新场景材质失败:', error);
        }
    }
    
    /**
     * 创建新材质
     */
    async createNewMaterial() {
        const name = prompt('请输入材质名称（字母、数字、下划线、连字符）:');
        if (!name) return;
        
        const displayName = prompt('请输入材质显示名称（可使用中文）:', name);
        if (!displayName) return;
        
        try {
            const newMaterial = await this.materialLibraryManager.createMaterial({
                name,
                displayName,
                description: '',
                ...this.getDefaultMaterialParams()
            });
            if (window.showManageMessage) {
                window.showManageMessage('材质创建成功', 'success');
            }
            
            // 重新加载材质库
            await this.loadMaterialLibrary();
            
            // 自动选中新材质
            await this.selectMaterial(newMaterial.id);
            
        } catch (error) {
            console.error('❌ 创建材质失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('创建材质失败: ' + error.message, 'error');
            } else {
                alert('创建材质失败: ' + error.message);
            }
        }
    }
    
    /**
     * 重命名材质（功能已禁用）
     */
    async renameMaterial() {
        if (window.showManageMessage) {
            window.showManageMessage('材质重命名功能已禁用', 'warning');
        } else {
            alert('材质重命名功能已禁用');
        }
    }
    
    /**
     * 复制材质
     */
    async duplicateMaterial() {
        if (!this.currentMaterial) {
            alert('请先选择一个材质');
            return;
        }
        
        const name = prompt('请输入新材质名称（字母、数字、下划线、连字符）:', this.currentMaterial.name + '_copy');
        if (!name) return;
        
        const displayName = prompt('请输入新材质显示名称:', this.currentMaterial.displayName + ' 副本');
        if (!displayName) return;
        
        try {
            // 复制当前材质的属性
            const materialData = { ...this.currentMaterial };
            delete materialData.id;
            delete materialData.createdAt;
            delete materialData.updatedAt;
            materialData.name = name;
            materialData.displayName = displayName;
            
            const newMaterial = await this.materialLibraryManager.createMaterial(materialData);
            if (window.showManageMessage) {
                window.showManageMessage('材质复制成功', 'success');
            }
            
            // 重新加载材质库
            await this.loadMaterialLibrary();
            
            // 自动选中新材质
            await this.selectMaterial(newMaterial.id);
            
        } catch (error) {
            console.error('❌ 复制材质失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('复制失败: ' + error.message, 'error');
            } else {
                alert('复制失败: ' + error.message);
            }
        }
    }
    
    /**
     * 删除材质
     */
    async deleteMaterial() {
        if (!this.currentMaterial) {
            alert('请先选择一个材质');
            return;
        }
        
        const confirmed = confirm(`确定要删除材质"${this.currentMaterial.displayName}"吗？`);
        if (!confirmed) return;
        
        try {
            await this.materialLibraryManager.deleteMaterial(this.currentMaterial.id);
            if (window.showManageMessage) {
                window.showManageMessage('材质删除成功', 'success');
            }
            
            // 清除当前选中
            this.currentMaterial = null;
            
            // 重新加载材质库
            await this.loadMaterialLibrary();
            
            // 禁用操作按钮
            document.getElementById('btn-rename-material').disabled = true;
            document.getElementById('btn-duplicate-material').disabled = true;
            document.getElementById('btn-delete-material').disabled = true;
            
        } catch (error) {
            console.error('❌ 删除材质失败:', error);
            
            // 检查是否是引用错误
            if (error.usedByMeshes && error.usedByMeshes.length > 0) {
                this.showMaterialInUseDialog(error.usedByMeshes);
            } else {
                if (window.showManageMessage) {
                    window.showManageMessage('删除失败: ' + error.message, 'error');
                } else {
                    alert('删除失败: ' + error.message);
                }
            }
        }
    }
    
    /**
     * 显示材质正在被使用的提示对话框
     * @param {Array} usedByMeshes - 引用列表（mesh级别）
     */
    showMaterialInUseDialog(usedByMeshes) {
        // 构建引用列表HTML
        let referencesHtml = '<div class="material-references-list" style="max-height: 300px; overflow-y: auto; margin-top: 10px;">';
        
        for (const ref of usedByMeshes) {
            referencesHtml += `
                <div class="reference-item" style="padding: 8px; margin: 5px 0; background: #f5f5f5; border-radius: 4px;">
                    <div style="font-size: 12px; color: #666;">
                        <div>📍 场景: ${ref.sceneId}</div>
                        <div>🎯 节点: ${ref.nodeId}</div>
                        <div>🔷 Mesh: ${ref.meshName || ref.meshId}</div>
                    </div>
                </div>
            `;
        }
        
        referencesHtml += '</div>';
        
        const modalHtml = `
            <div style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 10000; display: flex; align-items: center; justify-content: center;" id="material-in-use-modal" onclick="if(event.target === this) this.remove()">
                <div style="background: white; padding: 20px; border-radius: 8px; max-width: 500px; width: 90%; box-shadow: 0 4px 12px rgba(0,0,0,0.3);" onclick="event.stopPropagation()">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h3 style="margin: 0; color: #ff9800;">⚠️ 材质正在使用中</h3>
                        <button onclick="document.getElementById('material-in-use-modal').remove()" style="background: none; border: none; font-size: 24px; cursor: pointer; padding: 0; width: 30px; height: 30px; line-height: 1;">×</button>
                    </div>
                    <div style="margin-bottom: 20px;">
                        <p style="margin: 10px 0;">该材质正在被 <strong style="color: #ff9800;">${usedByMeshes.length}</strong> 个Mesh使用，无法删除。</p>
                        <p style="margin: 10px 0; color: #ff5722;">请先解除以下引用后再删除：</p>
                        ${referencesHtml}
                    </div>
                    <div style="text-align: right;">
                        <button onclick="document.getElementById('material-in-use-modal').remove()" style="padding: 8px 20px; background: #2196f3; color: white; border: none; border-radius: 4px; cursor: pointer;">知道了</button>
                    </div>
                </div>
            </div>
        `;
        
        document.body.insertAdjacentHTML('beforeend', modalHtml);
    }
    
    /**
     * 关闭材质编辑器
     */
    close() {
        this.modal.classList.remove('active');
        this.stopPreviewAnimation();
        
        // 清理预览场景
        if (this.previewMesh) {
            this.previewScene.remove(this.previewMesh);
            this.previewMesh.geometry.dispose();
            this.previewMesh.material.dispose();
            this.previewMesh = null;
        }
        
        this.currentModel = null;
        this.currentMaterialSettings = null;
    }
    
    /**
     * 打开材质浏览器
     */
    async openMaterialBrowser() {
        if (!this.materialLibraryManager) {
            console.error('❌ 材质库管理器未初始化');
            return;
        }
        
        // 显示浏览器窗口
        this.materialBrowser.style.display = 'flex';
        
        // 加载所有材质
        await this.loadMaterialsForBrowser();
        
        // 绑定搜索事件
        const searchInput = document.getElementById('material-browser-search-input');
        if (searchInput) {
            searchInput.oninput = (e) => {
                this.filterMaterialsInBrowser(e.target.value);
            };
        }
    }
    
    /**
     * 关闭材质浏览器
     */
    closeMaterialBrowser() {
        this.materialBrowser.style.display = 'none';
        this.selectedMaterialInBrowser = null;
        
        // 停止所有预览动画
        this.stopAllPreviewAnimations();
    }
    
    /**
     * 确认材质选择
     */
    async confirmMaterialSelection() {
        if (!this.selectedMaterialInBrowser) {
            alert('请先选择一个材质');
            return;
        }
        // 应用材质到模型
        await this.selectMaterialFromBrowser(this.selectedMaterialInBrowser);
        
        // 关闭浏览器
        this.closeMaterialBrowser();
    }
    
    /**
     * 加载材质到浏览器
     */
    async loadMaterialsForBrowser() {
        const grid = document.getElementById('material-browser-grid');
        if (!grid) return;
        
        try {
            const materials = await this.materialLibraryManager.loadMaterials();
            this.materials = materials;
            if (materials.length === 0) {
                grid.innerHTML = '<div class="material-grid-loading">材质库为空</div>';
                return;
            }
            
            // 渲染材质卡片
            this.renderMaterialCards(materials);
            
        } catch (error) {
            console.error('❌ 加载材质失败:', error);
            grid.innerHTML = '<div class="material-grid-loading">加载失败</div>';
        }
    }
    
    /**
     * 渲染材质卡片
     */
    renderMaterialCards(materials) {
        const grid = document.getElementById('material-browser-grid');
        if (!grid) return;
        
        grid.innerHTML = '';
        
        materials.forEach(material => {
            const card = this.createMaterialCard(material);
            grid.appendChild(card);
            
            // 创建预览
            this.createMaterialPreview(material, card);
        });
    }
    
    /**
     * 创建材质卡片
     */
    createMaterialCard(material) {
        const card = document.createElement('div');
        card.className = 'material-preview-card';
        card.dataset.materialId = material.id;
        
        const typeConfig = this.getMaterialTypeConfig()[material.materialType || 'MeshStandardMaterial'];
        const typeIcon = typeConfig?.icon || '💎';
        const typeName = material.materialType?.replace('Mesh', '').replace('Material', '') || 'Standard';
        
        card.innerHTML = `
            <div class="material-preview-canvas-container" id="preview-${material.id}">
                <!-- Canvas will be added here -->
            </div>
            <div class="material-preview-info">
                <div class="material-preview-name" title="${material.displayName || material.name}">
                    ${material.displayName || material.name}
                </div>
                <div class="material-preview-type">
                    <span>${typeIcon}</span>
                    <span class="material-type-badge">${typeName}</span>
                </div>
            </div>
        `;
        
        card.onclick = () => {
            // 取消之前的选中
            document.querySelectorAll('.material-preview-card').forEach(c => {
                c.classList.remove('selected');
            });
            
            // 选中当前
            card.classList.add('selected');
            this.selectedMaterialInBrowser = material.id;
        };
        
        return card;
    }
    
    /**
     * 创建材质预览
     */
    createMaterialPreview(material, card) {
        const container = card.querySelector('.material-preview-canvas-container');
        if (!container) return;
        
        // 创建Three.js场景
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a1a1a);
        
        // 创建相机
        const camera = new THREE.PerspectiveCamera(40, 1, 0.01, 100);
        camera.position.set(2.5, 2, 2.5);
        camera.lookAt(0, 0, 0);
        
        // 创建渲染器
        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
        renderer.setSize(180, 140);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        container.appendChild(renderer.domElement);
        
        // 添加灯光
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(5, 5, 5);
        scene.add(directionalLight);
        
        // 创建球体预览
        const geometry = new THREE.SphereGeometry(1, 64, 64);
        const threeMaterial = this.createThreeMaterial(material);
        const mesh = new THREE.Mesh(geometry, threeMaterial);
        scene.add(mesh);
        
        // 保存预览数据
        const previewData = {
            scene,
            camera,
            renderer,
            mesh,
            animationId: null
        };
        
        this.materialPreviews.set(material.id, previewData);
        
        // 启动动画
        const animate = () => {
            previewData.animationId = requestAnimationFrame(animate);
            mesh.rotation.y += 0.005;
            renderer.render(scene, camera);
        };
        animate();
    }
    
    /**
     * 根据材质数据创建Three.js材质
     */
    createThreeMaterial(materialData) {
        const materialType = materialData.materialType || 'MeshStandardMaterial';
        
        const baseProps = {
            color: new THREE.Color(materialData.color || '#ffffff')
        };
        
        let material;
        
        switch (materialType) {
            case 'MeshStandardMaterial':
                material = new THREE.MeshStandardMaterial({
                    ...baseProps,
                    metalness: materialData.metalness ?? 0.5,
                    roughness: materialData.roughness ?? 0.5,
                    emissive: new THREE.Color(materialData.emissive || '#000000'),
                    emissiveIntensity: materialData.emissiveIntensity || 0
                });
                break;
                
            case 'MeshPhongMaterial':
                material = new THREE.MeshPhongMaterial({
                    ...baseProps,
                    specular: new THREE.Color(materialData.specular || '#111111'),
                    shininess: materialData.shininess ?? 30,
                    emissive: new THREE.Color(materialData.emissive || '#000000'),
                    emissiveIntensity: materialData.emissiveIntensity || 0
                });
                break;
                
            case 'MeshLambertMaterial':
                material = new THREE.MeshLambertMaterial({
                    ...baseProps,
                    emissive: new THREE.Color(materialData.emissive || '#000000'),
                    emissiveIntensity: materialData.emissiveIntensity || 0
                });
                break;
                
            case 'MeshBasicMaterial':
                material = new THREE.MeshBasicMaterial(baseProps);
                break;
                
            case 'MeshPhysicalMaterial':
                material = new THREE.MeshPhysicalMaterial({
                    ...baseProps,
                    metalness: materialData.metalness ?? 0.5,
                    roughness: materialData.roughness ?? 0.5,
                    emissive: new THREE.Color(materialData.emissive || '#000000'),
                    emissiveIntensity: materialData.emissiveIntensity || 0,
                    clearcoat: materialData.clearcoat || 0,
                    clearcoatRoughness: materialData.clearcoatRoughness || 0,
                    transmission: materialData.transmission || 0
                });
                break;
                
            default:
                material = new THREE.MeshStandardMaterial(baseProps);
        }
        
        return material;
    }
    
    /**
     * 停止所有预览动画
     */
    stopAllPreviewAnimations() {
        this.materialPreviews.forEach((previewData, materialId) => {
            if (previewData.animationId) {
                cancelAnimationFrame(previewData.animationId);
            }
            if (previewData.renderer) {
                previewData.renderer.dispose();
            }
            if (previewData.mesh) {
                previewData.mesh.geometry.dispose();
                previewData.mesh.material.dispose();
            }
        });
        this.materialPreviews.clear();
    }
    
    /**
     * 筛选材质
     */
    filterMaterialsInBrowser(searchText) {
        const filtered = this.materials.filter(m => 
            (m.displayName && m.displayName.toLowerCase().includes(searchText.toLowerCase())) ||
            (m.name && m.name.toLowerCase().includes(searchText.toLowerCase()))
        );
        
        this.stopAllPreviewAnimations();
        this.renderMaterialCards(filtered);
    }
    
    /**
     * 从浏览器选择材质
     */
    async selectMaterialFromBrowser(materialId) {
        try {
            const material = await this.materialLibraryManager.getMaterial(materialId);
            if (!material) {
                console.error('❌ 材质不存在:', materialId);
                return;
            }
            
            this.currentMaterial = material;
            this.currentMaterialSettings = material;
            
            // 更新显示名称
            const nameInput = document.getElementById('material-current-name');
            if (nameInput) {
                nameInput.value = material.displayName || material.name;
            }
            
            // 应用材质到模型
            await this.materialLibraryManager.applyMaterialToModel(this.currentModel.id, materialId);
            
            // 更新面板参数
            this.updatePanelFromMaterial(material);
            
            // 刷新场景
            await this.refreshSceneMaterials();
            
            if (window.showManageMessage) {
                window.showManageMessage(`已应用材质：${material.displayName || material.name}`, 'success');
            }
        } catch (error) {
            console.error('❌ 选择材质失败:', error);
            if (window.showManageMessage) {
                window.showManageMessage('选择材质失败: ' + error.message, 'error');
            }
        }
    }
}

// 创建全局实例
let materialEditorInstance = null;

/**
 * 获取材质编辑器实例
 */
export function getMaterialEditor() {
    if (!materialEditorInstance) {
        materialEditorInstance = new MaterialEditor();
    }
    return materialEditorInstance;
}

// 暴露到全局
window.getMaterialEditor = getMaterialEditor;

/**
 * 选择纹理文件
 * @param {string} textureType - 纹理类型（map, normalMap, aoMap等）
 */
window.selectTextureFile = function(textureType) {
    const input = document.getElementById('texture-file-input');
    if (!input) return;
    
    // 设置当前纹理类型
    input.dataset.textureType = textureType;
    
    // 触发文件选择
    input.click();
};

/**
 * 清除纹理
 * @param {string} textureType - 纹理类型
 */
window.clearTexture = function(textureType) {
    const inputMap = {
        'map': 'mat-map',
        'normalMap': 'mat-normal-map',
        'aoMap': 'mat-ao-map',
        'roughnessMap': 'mat-roughness-map',
        'metalnessMap': 'mat-metalness-map'
    };
    
    const inputId = inputMap[textureType];
    if (inputId) {
        const input = document.getElementById(inputId);
        if (input) {
            input.value = '';
            
            // 触发预览更新
            const materialEditor = getMaterialEditor();
            if (materialEditor) {
                materialEditor.updatePreview();
            }
        }
    }
};

// ✅ 全局辅助函数（用于保存按钮）
window.materialEditorSave = function() {
    const editor = getMaterialEditor();
    if (editor) {
        editor.saveFromPanel();
    }
};

/**
 * 打开材质浏览器
 */
window.openMaterialBrowser = async function() {
    const editor = getMaterialEditor();
    if (!editor) return;
    
    await editor.openMaterialBrowser();
};

/**
 * 关闭材质浏览器
 */
window.closeMaterialBrowser = function() {
    const editor = getMaterialEditor();
    if (!editor) return;
    
    editor.closeMaterialBrowser();
};

/**
 * 确认材质选择
 */
window.confirmMaterialSelection = async function() {
    const editor = getMaterialEditor();
    if (!editor) return;
    
    await editor.confirmMaterialSelection();
};

